﻿/*
 * msgagent.cpp
 *
 *  Created on: Aug 19, 2017
 *      Author: vte
 */

#include <dm/export.hpp>

#define DM_API_OS_MSG DM_API_EXPORT

#include <dm/os/msg/msgagent.hpp>

#ifndef WIN32
#include <unistd.h>
#endif

namespace dm{
namespace os{
namespace msg{

using namespace dm::msg;

CMsgAgent::CMsgAgent():CMsgMgr(),
		m_pRequest(m_qRequest->getCurPos()),
		m_pAnswer(m_qAnswer->getCurPos()){
#ifdef WIN32
	m_mod = GetCurrentProcessId();
#else
	m_mod = getpid();
#endif
}

void CMsgAgent::sendMsg( CMsgInfo& msg ){
	msg.setMod(m_mod);
	msg.setTs_now();

	push(msg);
}

/**
 * 获取消息。
 * @param msg
 * @return 是否获取成功。
 * @note 优先获取请求消息，然后再获取应答消息
 */
bool CMsgAgent::tryGet( CMsgInfo& msg ){
	if( tryGetRequeset(msg) )
		return true;
	else
		return tryGetAnswer(msg);
}

bool CMsgAgent::tryGetRequeset( CMsgInfo& msg ){
	while( m_qRequest->pop(m_pRequest,msg) ){
		if( msg.getMod()!=m_mod )
			return true;
	}

	return false;
}

bool CMsgAgent::tryGetAnswer( CMsgInfo& msg ){
	while( m_qAnswer->pop(m_pAnswer,msg) ){
		if( msg.getMod()!=m_mod )
			return true;
	}

	return false;
}

void CMsgAgent::wait( CMsgInfo& msg ){
	while( !tryGetRequeset(msg) && !tryGetAnswer(msg) );
}

void CMsgAgent::wait4requset( CMsgInfo& msg ){
	while( true ){
		m_qRequest->wait(m_pRequest,msg);
		if( msg.getMod()!=m_mod )
			break;
	}
}

void CMsgAgent::wait4answer( CMsgInfo& msg ){
	while( true ){
		m_qAnswer->wait(m_pAnswer,msg);
		if( msg.getMod()!=m_mod )
			break;
	}
}

void CMsgAgent::resetRequest( dm::CTimeStamp::s_t secsBefore,const dm::CTimeStamp& now ){
	if( secsBefore==0 )
		m_pRequest = m_qRequest->getCurPos();
	else{
		CMsgInfo msg;
		while( m_pRequest!=m_qRequest->getCurPos() ){
			m_qRequest->pop(m_pRequest,msg);
			if( !msg.getTs().isTimeout_sec(secsBefore,now) ){
				--m_pRequest;
				break;
			}
		}
	}
}

void CMsgAgent::resetAnswer( dm::CTimeStamp::s_t secsBefore,const dm::CTimeStamp& now ){
	if( secsBefore==0 )
		m_pAnswer = m_qAnswer->getCurPos();
	else{
		CMsgInfo msg;
		while( m_pAnswer!=m_qAnswer->getCurPos() ){
			m_qAnswer->pop(m_pAnswer,msg);
			if( !msg.getTs().isTimeout_sec(secsBefore,now) ){
				--m_pAnswer;
				break;
			}
		}
	}
}

}
}
}


